package dymnd.ui;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;

import javax.swing.JPanel;

import dymnd.image.Layer;
public class Canvas extends JPanel	{
	
	private static final int BACKGROUND_RECT_SIZE = 5;
	private static final Color BACKGROUND_RECT_COLOR = new Color(50, 50, 50);
	
	BufferedImage buffer;
	public Canvas(int width, int height)	{
		buffer = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
		//setBackground(Color.gray);
	}
	
	/**
	 * Replaces any pixels within the specified Rectangle2D with any inside any of the new set of layers
	 * @param layers - the layers to draw on
	 * @param bounds - the area to update
	 */
	public void paintLayers(ArrayList<Layer> layers, Rectangle2D bounds, boolean repaint)	{
		Graphics2D g = buffer.createGraphics();
		g.setComposite(AlphaComposite.Src);
		g.setColor(new Color(0, 0, 0, 0));
		g.fill(bounds);
		
		g.setComposite(AlphaComposite.SrcOver);
		for(int i = 0; i < layers.size(); i++)	{
			//g.drawRect((int)bounds.getX(), (int)bounds.getY(), (int)bounds.getWidth(), (int)bounds.getHeight());
			g.drawImage(layers.get(i).getSubimage((int)bounds.getX(), (int)bounds.getY(), (int)bounds.getWidth(), (int)bounds.getHeight()), (int)bounds.getX(), (int)bounds.getY() ,this);
			
		}
		
		g.dispose();
		
		if(repaint)
			repaint();
	}
	
	/**
	 * Replaces any pixels within the specified Rectangle2D with any inside any of the new set of layers
	 * @param layers - the layers to draw on
	 * @param bounds - the area to update
	 * @param scratchLayer - a scratch layer, containing temporary drawing data
	 * @param activeLayer - the currently active layer, to draw the scratchLayer on top of
	 */
	public void paintLayers(ArrayList<Layer> layers, Layer scratchLayer, int activeLayer, Rectangle2D bounds, boolean repaint)	{
		Graphics2D g = buffer.createGraphics();
		g.setComposite(AlphaComposite.Src);
		g.setColor(new Color(0, 0, 0, 0));
		g.fill(bounds);
		
		g.setComposite(AlphaComposite.SrcOver);
		for(int i = 0; i < layers.size(); i++)	{
			//g.drawRect((int)bounds.getX(), (int)bounds.getY(), (int)bounds.getWidth(), (int)bounds.getHeight());
			g.drawImage(layers.get(i).getSubimage((int)bounds.getX(), (int)bounds.getY(), (int)bounds.getWidth(), (int)bounds.getHeight()), (int)bounds.getX(), (int)bounds.getY() ,this);
			
		}
		
		g.dispose();
		
		if(repaint)
			repaint();
	}
	
	/**
	 * Composites a single layer on top of any existing pixels
	 * @param layer - layer to draw on top of everything.
	 * @param bounds - the area to composite to the buffer.
	 */
	public void compositeLayer(Layer layer, Rectangle2D bounds, boolean repaint)	{
		Graphics2D g = buffer.createGraphics();
		g.drawImage(layer.getSubimage((int)bounds.getX(), (int)bounds.getY(), (int)bounds.getWidth(), (int)bounds.getHeight()), (int)bounds.getX(), (int)bounds.getY() ,this);
		
		if(repaint)
			repaint();
	}
	
	
	public void paintComponent(Graphics arg0)	{
		Graphics2D g = (Graphics2D) arg0;
		
		g.setColor(Color.white);
		g.fillRect(0, 0, getWidth(), getHeight());
		
		if(getParent() instanceof DragViewport)	{
			Rectangle visibleRect = ((DragViewport)getParent()).getViewRect();
			//System.out.println(visibleRect.getX() + " " + visibleRect.getY());
					
			g.drawImage(buffer.getSubimage(visibleRect.x, visibleRect.y, visibleRect.width, visibleRect.height), visibleRect.x, visibleRect.y, this);
		}	else	{
			
			g.drawImage(buffer, 0, 0,this);
			System.out.println("Oh no! Canvas is drawing using slow method! Check dymnd.ui.Canvas.paintComponent(Graphics arg0)");
		}
		
		
		
	}
	
	//draws a checkered background
	/*private void paintBackground(Graphics2D g)	{
		boolean darkenRect = true;
		for(int x = 0; x <= (getWidth() + BACKGROUND_RECT_SIZE)/BACKGROUND_RECT_SIZE; x++)	{
			for(int y  = 0; y <= (getHeight() + BACKGROUND_RECT_SIZE)/BACKGROUND_RECT_SIZE; y++)	{
				if(darkenRect)	{
					g.setColor(BACKGROUND_RECT_COLOR);
					darkenRect = false;
				}	else	{
					g.setColor(Color.white);
					darkenRect = true;
				}
				
				g.fill(new Rectangle2D.Double(x*BACKGROUND_RECT_SIZE, y*BACKGROUND_RECT_SIZE, BACKGROUND_RECT_SIZE, BACKGROUND_RECT_SIZE));
			}
		}
	}*/
	
	
}